package net.maku.framework.common.utils;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 线程池工具类
 *
 * @Author: qr
 * @Version: 1.0
 */
public class ThreadPoolExecutorUtil {
    /**
     * 线程池中所存放的线程数
     */
    private static final int CORE_POOL_SIZE = 32;
    /**
     * 线程池中允许的最大线程数
     */
    private static final int MAX_CORE_POOL_SIZE = 64;
    /**
     * 等待获取线程时间参数
     */
    private static final int KEEP_ALIVE_TIME = 1000;
    /**
     * 执行前用于保持任务的队列大小
     */
    private static final int BLOCKING_QUEUE_SIZE = 100;
    /**
     * 等待获取线程时间参数单位
     */
    private static final TimeUnit UNIT = TimeUnit.MILLISECONDS;

    /**
     * 使用ThreadPoolExecutor自定义线程池
     * 说一下使用ThreadPoolExecutor的好处
     * 1.可以实时获取线程池内线程的各种状态
     * 2.可以根据机器来动态调整线程池大小
     * threadFactory->线程创建工厂使用ArrayBlockingQueue阻塞线程队列
     * ArrayBlockingQueue会初始化指定容量的数组，初始化非公平的重入锁，初始化读等待队列，初始化写等待队列。
     * handler->拒绝策略使用ThreadPoolExecutor->下的DiscardOldestPolicy抛弃当前的任务，
     * 将当前线程异常既判定为线程死亡进行抛弃，继续执行线程任务
     */
    private static final ThreadPoolExecutor THREAD_POOL = new ThreadPoolExecutor(CORE_POOL_SIZE,
            MAX_CORE_POOL_SIZE,
            KEEP_ALIVE_TIME,
            UNIT,
            new ArrayBlockingQueue<>(BLOCKING_QUEUE_SIZE),
            Executors.defaultThreadFactory(),
            new CustomRejectedExecutionHandler()
    );

    private ThreadPoolExecutorUtil() {
    }

    public static ThreadPoolExecutor getThreadPool() {
        return THREAD_POOL;
    }

    public static void close() {
        THREAD_POOL.allowCoreThreadTimeOut(true);
    }
}
